iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
佛心分享-SideProject30

營養師想做一個飲食建議產品系列 第 28 篇

Day28 - 上線後的費用防呆 : 預算警報與流量限制

  • 分享至 

  • xImage
  •  

把網址分享出去之前,想到一個問題:如果真的有人狂點,要付多少錢?

Day27 拿到公開網址之後,第一個念頭是分享給朋友玩玩看。但緊接著冒出的疑慮是:這支 API 完全沒有身份驗證,CORS 也設成允許所有來源,理論上任何人都能繞過前端介面直接對著 API 打,這代表我完全不知道流量上限在哪裡,如果成本超支了怎麼辦?為了避免這種事情發生,我們先來搞懂「AWS 到底怎麼收錢」,再來看可以為這個專案做了哪些防範,以及哪些防範其實這次沒做成。

🧱 地基概念一:AWS 怎麼計費?

1. 用多少付多少(Pay as you go)

雲端跟「月租型」手機方案不一樣,比較像水電費:用得多付得多,沒用就不收錢。好處是小專案很便宜;壞處是沒有人幫你設上限,流量暴增時帳單也會跟著暴增。

2. 每個服務各自算錢,單位都不同

一個專案會用到好幾個服務,每個服務的收費方式不一樣,最後帳單是全部加起來:

服務 它在做什麼 大概按什麼收費
S3 放網站檔案 存了多少資料、被讀取幾次
CloudFront 讓全世界快速打開網站 傳出去多少資料量
API Gateway API 的大門 被呼叫幾次
Lambda 執行後端程式 執行幾次,加上每次跑多久、用多少記憶體
Bedrock 呼叫 AI 模型 按 token 收費(輸入多少字、輸出多少字)

白話一點:token 就是 AI 讀寫文字的「計價單位」,可以先想成字數。你問得越長、AI 答得越長,就越貴。

3. 免費額度(Free Tier)

多數服務每個月會給一份免費額度,用在額度內不收費,超過才開始算錢。像 S3、CloudFront、API Gateway、Lambda 的額度對小專案都很大方。但免費額度的規則和數字會調整,實際以 AWS 官方價格頁和 Billing 頁面為準,這邊不寫死數字。

4. 重點:不是每個服務都有免費額度

Bedrock 沒有這份「額度緩衝」,用了就計費。所以這個專案的費用風險,幾乎都集中在呼叫 AI 的那一步。

5. 帳單看得到,但不是即時的

Billing 頁面的數字會有延遲,不是花一塊錢就立刻跳一塊錢。這點會影響後面「警報」能多快通知你。

🧱 地基概念二:我這個專案一次送出會花多少?

先把 Bedrock 的收費拆開來看,這是整篇最重要的觀念。

1. 按 token 算,不是按呼叫次數

原本直覺以為「打一次 API 就是一筆固定費用」。實際上 Bedrock 看的是「這次用了多少 token」,內容越長就越貴,不是打一次收一次。

2. input 和 output 分開計價

  • input token:你送進去的內容(prompt),像是指令加上參考資料。
  • output token:AI 回傳的內容。

兩者的用量不同,單價通常也不同(output 通常比較貴,實際以 Bedrock 價格頁為準),所以要分開看。

3. 成本主要來自「送進去多少」

專案生成菜單時,會把候選食物清單(每個餐次最多 15 筆真實食物的完整資料)整包放進 prompt 讓 AI 挑,這是大宗的 input;AI 只需要回傳精簡的 JSON(選中的食物編號加一句建議),output 很小。所以這個專案的成本,主要取決於 input 有多長,而不是 AI 回答多長。

4. 一次送出 ≠ 一次呼叫

使用者按一次「送出」,後端其實會呼叫 2 到 3 次 Bedrock(分析、生成菜單,加上可能的重試)。估算成本時要乘上這個倍數。

5. 把它們串成一條粗估式

一次送出的成本 ≈ 呼叫次數 ×(input token 數 × input 單價 + output token 數 × output 單價)

示範(數字都是我假設的,不是實際價格或實際用量):

  • 假設 input 單價每百萬 token 1 美元、output 單價每百萬 token 5 美元
  • 一次呼叫:input 10,000 token、output 500 token
  • input 花 10,000 × 1 ÷ 1,000,000 = 0.01 美元;output 花 500 × 5 ÷ 1,000,000 = 0.0025 美元
  • 一次呼叫約 0.0125 美元,一次送出(3 次呼叫)約 0.0375 美元

這條式子是我整理的粗估方法,不是 AWS 的官方公式。想換成真實數字,只要把自己的 token 用量和 Bedrock 價格頁的單價代進去。

6. 模型單價是成本槓桿

同樣的用量,換一個單價較低的模型,成本就跟著降。我的專案用的是 Claude Haiku 4.5,單價較低:因為 AI 在這裡只負責「從候選清單挑食物」,份數等核心計算都是程式算的,對模型能力要求不高,便宜的模型就夠用。反過來說,如果任務很難、必須用更貴的模型,同樣的用量帳單就會明顯變高。

7. 最後用真實帳單核對

估算完,再拿 Bills和估算比對,對不上就代表你的成本模型哪裡估算得不準。

🧱 地基概念三:為什麼要擔心「公開網址」?

目前的API 沒有任何身份驗證,CORS 也設成允許所有來源。

CORS 只是瀏覽器的規則,不是防護。 Day26 提過,curl 不受同源政策限制。只要知道 API 網址,任何人都可以用程式直接對它發請求,完全不經過我的前端畫面。所以 CORS 不能當作防護網。

把兩件事放在一起看:

  • 任何人都打得到 API
  • 每打一次,可能就要付一次 Bedrock 的錢

這就是「最壞情況」:有人寫個迴圈一直打,帳單就一直長,沒有東西會自動叫停。套用上一節的估算(同樣是示範用的假設數字): 一次送出約 0.0375 美元,被打 1 萬次就是約 375 美元。「次數 × 單次成本」沒有上限。

🧱 地基概念四:有哪些防範手段?

新手可以把防範想成三種不同性質的東西:

類型 白話比喻 例子
預防:讓別人打不進來 大樓門禁 API Key、身份驗證
限流:就算打進來也限制速度 餐廳限制同時入座人數 Lambda 保留併發、API Gateway 限流
警報:花多了會通知你 電表超過度數就響鈴 AWS Budgets

先認識幾個這篇會用到的名詞:

什麼是「限流」?

限流就是替請求的「速度或數量」設一道上限,超過的就不處理(直接拒絕,請對方稍後再來)。比喻:餐廳門口限制同時入座的人數,客人再多也不會超過。

常見的限法有兩種:

  • 限「同時」:
    同一個瞬間最多處理幾個。這就是下面要講的「併發」,Lambda 的保留併發屬於這一種。
  • 限「頻率或總量」:
    每秒最多幾次、每天最多幾次。API Gateway 的限流設定、Usage Plan 屬於這一種。

為什麼限流跟省錢有關? 每呼叫一次 Bedrock 就要花錢,限流能讓「最壞情況」從無上限,變成「最多只能這麼快」。注意:只限速度不等於限總額,要限總額得靠「每天最多幾次」這類額度。

什麼是「併發」(concurrency)?

併發就是「同一個瞬間,有幾個 Lambda 正在同時跑」。不是「一天總共跑幾次」,而是「現在這一刻同時有幾個」。

用小吃店比喻:

  • 每一位客人點餐 = 一次 API 請求
  • 每一個正在被煮的那一份餐 = 一個正在執行的 Lambda
  • 店裡有幾個爐子,就同時最多煮幾份 = 併發額度

如果有 10 個爐子,同時來了 15 位客人,那 10 位先煮,剩下 5 位要等(在 Lambda 就是被拒絕,回傳「太多請求」的錯誤)。

併發數大概等於:每秒來幾個請求 × 每個請求要跑幾秒。 例如每秒 5 個請求、每個跑 2 秒,同一瞬間大約就有 10 個在跑。「每個請求要跑幾秒」也包含等 AI 回應的時間。我們的 Lambda 要等 Bedrock 生成內容,每次可能跑好幾秒,所以請求不用很多,併發就會很快被用完。

什麼是「保留併發」?

保留併發(ReservedConcurrentExecutions)是替某個函式「預留 N 個爐子、而且最多只能用這 N 個」。這樣做有兩個效果:

  • 保證這個函式一定有爐子可用,不會被其他函式搶光。
  • 同時也替它設了上限,被狂打時,同一瞬間最多只跑 N 個,花費速度也被壓住。

什麼是「TPM」?

TPM 是 Tokens Per Minute,意思是「每分鐘最多能處理多少 token」,是 AWS 替每個 Bedrock 模型設的用量上限。它也是一種限流:前面講的併發是限「同時幾個」,API Gateway 是限「幾次」,TPM 則是用「token 量」來限速。三個重點:

  • 每個模型各自有額度,而且額度不是自動有的,有些模型的額度一開始是 0,要先申請開通才能用。
  • 超過額度時,請求會被拒絕或要重試。
  • 它是 AWS 的額度,不是為了幫你省錢設計的。我查到自己用的模型額度是 500 萬 TPM,遠高於這個專案的實際用量,所以不能當作費用防護。

額度可以在 Service Quotas 的 Amazon Bedrock 底下查看,每個帳號不同。

AWS Budgets:花費警報

設定一個預算金額,實際花費超過一定比例時寄信通知你。注意:它只會通知,不會幫你擋下來。

🔧 實際操作

第一步:盤點風險在哪

回頭看上面那張表:S3、CloudFront、API Gateway、Lambda 都有大方的免費額度,風險低。真正的風險集中在 Bedrock,因為它沒有免費額度、按 token 收費,而且流量沒有任何門檻擋著。

所以防範的重點很明確:不要讓人無限制地呼叫會觸發 Bedrock 的 API。

第二步:嘗試 Lambda 保留併發上限(沒成功)

前面提到的限流手段中,最直接的是替 Lambda 設定「保留併發」,限制它同時最多跑幾個。我嘗試設定,結果發現這個 AWS 帳號的 Lambda 總併發額度只有 10,而 AWS 規定「沒被保留的額度不能低於 10」,所以設不了。(額度可以申請調高,步驟寫在後面;目前專案只分享給少數人所以沒有這個需求,就先不申請了。)

為什麼設不了? 用小吃店比喻:

  • 整間店總共只有 10 個爐子(帳號總併發額度 = 10)。
  • AWS 規定:至少要留 10 個爐子給「沒預訂的人」共用。
  • 我想替某個函式預訂 N 個爐子,但 10 減 N 必須大於等於 10,所以 N 只能是 0。
  • 結論:一個爐子都預訂不了,這個方法在目前的額度下完全用不上。

如果總額度是 1000,我就可以預訂例如 5 個,其餘 995 個照樣共用,這個方法才有意義。
https://ithelp.ithome.com.tw/upload/images/20261011/20183959JHLlzf43BD.png

為什麼一開始只有 10,而不是文件上寫的 1000?

  • 1000 是 AWS 文件上寫的「預設值」,但這個數字是給已經使用一段時間的帳號。
  • AWS 對新開的帳號,通常會先給比較低的服務額度,一般認為是風險控管:避免新帳號被盜用或誤操作後,瞬間開出大量資源、產生天價帳單。
  • 隨著帳號有正常的使用紀錄,額度會慢慢被調高,或是自己申請調高。
  • AWS 不會逐一說明每個帳號為什麼是這個數字,所以上面是一般常見的原因,不是針對我這個帳號的診斷。

這個發現本身也是一課:想加一道保護,結果先撞到另一個帳號層級的限制。 雲端服務常常彼此牽制,不是想加就能馬上加。

反過來想: 總額度只有 10,其實等於這個帳號同一瞬間最多只能跑 10 個 Lambda,超過的請求會被拒絕。這在無意中也算一種上限,但它是「帳號本身的限制」,不是我設計的防護,不能當作已經防住,而且一旦額度被調高就不存在了。

第三步:設定 AWS Budgets 帳單警報

因為主動限流做不了,我退而求其次,設定每月 5 美元的預算,實際花費超過 80% 和 100% 各寄一次通知信。下面五張是我實際的 AWS 畫面,照著「設定好之後,怎麼確認它有在運作」的順序看。

圖 1|Budgets 清單頁:我設了哪些預算
https://ithelp.ithome.com.tw/upload/images/20261011/20183959gqF2KtibKa.png

  • Name:預算名稱。ai-diet-copilot-monthly-5usd 是我替這個專案建的,意思是「每月 5 美元」。另一個 My Monthly Cost Budget 是 AWS 範本的預設名稱,這篇只看前者。
  • Budget:預算金額,兩個都是 5 美元。
  • Thresholds(門檻):黃色的 Exceeded (1) 代表「有 1 個警報門檻已經被超過」。它不等於花費超過 5 美元,是哪一個門檻看圖 3。
  • Health status: Healthy:預算本身運作正常的意思,跟有沒有超標是兩件事。

圖 2|預算詳細頁:現在花了多少、預計花多少
https://ithelp.ithome.com.tw/upload/images/20261011/20183959HBHVZcezOa.png

從圖 1 點進預算名稱就會看到。紅框是這頁最重要的兩個數字:

  • Current vs. budgeted(目前 vs 預算):已經花 4.44 美元,占預算 5 美元的 88.82%。
  • Forecasted vs budgeted(預測 vs 預算):AWS 依目前的花費速度推估,整個月大概會花 4.80 美元(96.08%)。這只是估計,不是已經發生的花費。
  • 右邊 Alerts 卡片的 Exceeded (1),就是圖 1 那個黃色字;點下方的 View all alerts 就能看是哪一個門檻。

圖 3|點擊左下角的 View all alerts:兩道警報門檻各自的狀態
https://ithelp.ithome.com.tw/upload/images/20261011/201839591P28d02pzb.png
這就是前面說的「80% 和 100% 各寄一次通知」,兩張卡片各是一道門檻:

  • Actual cost > 80%:
    實際花費超過預算的 80%(4 美元)就觸發。狀態是 Exceeded,代表已經超過。
  • Actual cost > 100%:
    實際花費超過 5 美元才觸發。狀態是 Not exceeded,代表還沒到。
  • 所以圖 1 的 Exceeded (1),指的就是這裡 80% 的這一道。
  • Actions 是空的(-):超過門檻時只會通知我,不會自動做任何事,呼應前面講的「警報不會幫你擋下來」。

圖 4|真正收到的警報信
https://ithelp.ithome.com.tw/upload/images/20261011/201839590jP6imPqG7.png

設定警報最怕「設了卻不知道有沒有用」,所以我去信箱確認:2026/10/09 收到 AWS Budgets 寄來的信,內容翻成白話是:

  • 我設的預算 ai-diet-copilot-monthly-5usd,這個月的實際花費超過了 4.00 美元(門檻)。
  • 當下的實際花費是 4.39 美元(表格最後一欄 ACTUAL Amount)。
  • 表格依序是:預算名稱、類型(Cost 成本)、預算金額(5 美元)、警報類型(ACTUAL 實際花費)、門檻、當下金額。

這封信證明整條通知流程有走通:花費超過門檻,AWS 就會寄信到我設定的信箱。

圖 5|Bills:帳單實際長怎樣
https://ithelp.ithome.com.tw/upload/images/20261011/20183959MVehBLCtex.png

Budgets 說明「花了多少」,Bills 才說明「錢花在哪裡」。入口:Console 搜尋 Billing,左側選 Bills。

  • Billing period:計費期間是 10/1 到 10/31,AWS 是「按月」算錢的。
  • Bill status: Pending:本月還沒結束,這是預估值,月底才會結算。
  • Amazon Web Services, Inc.:0.00 美元:一般 AWS 服務(S3、CloudFront、API Gateway、Lambda 等)目前都在免費額度內,沒有收錢。
  • Amazon Web Services, Inc. - Marketplace:4.44 美元:全部的花費都在這一列。Marketplace 是 AWS 上第三方商品的計費管道,跟一般服務分開算。
  • Estimated grand total:4.44 美元,跟圖 2 的 Amount spent 一致。

看完這五張圖的結論: 警報有觸發、信有寄到,這道「被動警報」確實在運作。但要注意時間點:收到信的時候已經花了 4.39 美元,離 5 美元只差不到 1 美元。警報是「提醒」,不是「幫忙擋住」。

目前的防線總整理

防線 類型 狀態
Lambda 保留併發上限 限流(主動擋) 帳號額度只有 10,設定不了
AWS Budgets 帳單警報 警報(被動通知) 已設定,且已實際觸發並收到信(圖 3、圖 4)
API Key + Usage Plan 預防加限流 只是規劃,還沒做

誠實承認:這只是一道被動警報,不是真正的防護。 因為帳單數字有延遲,等信寄到時,錢可能已經花掉了。它比什麼都沒有好,但不能當作「已經防住」。如果之後真的要開放給更多人用,該做的是申請調高 Lambda 併發額度,或加一個 API Key 加 Usage Plan 限制呼叫來源。這兩件事目前先記錄下來,不急著做。

如果要申請調高額度,怎麼做?

以下是我讀官方做法整理的步驟,我還沒有實際送出申請,先寫在文章裡當作之後的備忘:

  1. 登入 AWS Console,確認右上角的 Region(額度是「每個 Region 各自計算」,要申請你放 Lambda 的那個 Region)。
  2. 搜尋並進入 Service Quotas。
  3. 左邊選 AWS services,選擇 AWS Lambda。
  4. 找到 Concurrent executions,點進去。
  5. 按 Request increase at account level(在帳號層級申請調高)。
  6. 輸入想要的新數字(例如 100 或 1000),送出申請。
  7. 等 AWS 回覆。申請本身免費;AWS 可能會自動核准,也可能要補充用途說明,新帳號甚至有可能被拒絕。

申請時的小提醒:

  • 數字不用一次要太大,依實際需求先要一個合理的值。
  • 額度調高之後,保留併發這個方法才能用,但同時「天然的 10 上限」也不見了,所以調高之後更要記得設保留併發或限流。

之後想做、但還沒做的事

以下是我讀資料得知的方向,不是我做過的事,先記錄下來:

  • 申請調高 Lambda 併發額度(步驟見上一節),再回頭設定保留併發。
  • API Key 加 Usage Plan:讓 API Gateway 只接受帶著 Key 的請求,並限制每秒、每天的呼叫次數。
  • API Gateway 本身的限流(throttling)設定,也是限制呼叫速度的做法。

目前專案只是作品集 Demo、網址只分享給少數人,所以先記錄、不急著做。如果要開放給不特定的人使用,這幾項就必須補上。

小結

  • AWS 是「用多少付多少」,每個服務各自計費,沒有人預設幫你設上限。
  • 這個專案的費用風險集中在 Bedrock(按 token 計費、沒有免費額度)。
  • CORS 不是防護,知道網址的人都能直接打 API。
  • 防範有三種性質:預防、限流、警報。我只做到最弱的一種(被動警報),而且它真的有觸發、有寄信。

上一篇
Day27 - 前端部署
下一篇
Day29 - 觀測與回顧
系列文
營養師想做一個飲食建議產品 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言